#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""

from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import

Root权限管理器 - 单点Root权限维持闭环系统
实现强制Root权限校验和目标环境精准画像生成
"""

import os
import sys

# Python 2/3 兼容性处理
if sys.version_info[0] == 2:
    string_types = basestring
    text_type = unicode
    def iteritems(d):
        return d.iteritems()
    def itervalues(d):
        return d.itervalues()
else:
    string_types = str
    text_type = str
    def iteritems(d):
        return d.items()
    def itervalues(d):
        return d.values()
import json
import subprocess
import platform
import time
from datetime import datetime
from pathlib import Path





class RootPrivilegeManager:
    """Root权限管理器 - 权限校验与环境探测"""
    
    def __init__(self):
        self.is_root = False
        self.environment_profile = {}
        self.detection_timestamp = int(time.time())
        
    def verify_root_privilege(self):
        """强制Root权限校验"""
        try:
            # 检查EUID是否为0
            if os.geteuid() != 0:
                print("[-] 错误: 需要Root权限执行此工具")
                print("[-] 请使用 'sudo' 或切换到root用户后重试")
                return False
                
            # 验证实际权限
            try:
                # 尝试写入系统目录验证权限
                test_file = "/tmp/.root_test"
                with open(test_file, 'w') as f:
                    f.write("root_test")
                os.remove(test_file)
                
                self.is_root = True
                print("[+] Root权限验证通过")
                return True
                
            except PermissionError:
                print("[-] 权限验证失败: 无法写入系统目录")
                return False
                
        except Exception as e:
            print("[-] 权限校验异常: {}".format(e))
            return False
    
    def detect_system_info(self):
        """系统信息检测"""
        try:
            system_info = {}
            
            # 操作系统信息
            if platform.system() == "Linux":
                # 读取发行版信息
                try:
                    with open('/etc/os-release', 'r') as f:
                        os_release = f.read()
                    
                    # 解析发行版
                    for line in os_release.split('\n'):
                        if line.startswith('PRETTY_NAME='):
                            system_info['os_name'] = line.split('=')[1].strip('"')
                        elif line.startswith('VERSION_ID='):
                            system_info['os_version'] = line.split('=')[1].strip('"')
                        elif line.startswith('ID='):
                            system_info['os_id'] = line.split('=')[1].strip('"')
                            
                except FileNotFoundError:
                    system_info['os_name'] = "Unknown Linux"
                    
            else:
                system_info['os_name'] = platform.system()
                system_info['os_version'] = platform.release()
                
            # 内核版本
            system_info['kernel'] = platform.release()
            
            # 架构信息
            system_info['architecture'] = platform.machine()
            
            return system_info
            
        except Exception as e:
            print("[-] 系统信息检测失败: {}".format(e))
            return {}
    
    def detect_security_tools(self):
        """安全工具检测"""
        try:
            security_info = {
                'edr_detected': False,
                'firewall_active': False,
                'fim_detected': False,
                'security_tools': []
            }
            
            # 检测EDR/安全软件进程
            edr_patterns = [
                'crowdstrike', 'carbonblack', 'cylance', 'sentinelone',
                'symantec', 'mcafee', 'kaspersky', 'bitdefender',
                'fireeye', 'trendmicro', 'sophos', 'avast'
            ]
            
            try:
                # 获取进程列表
                result = subprocess.run(['ps', 'aux'], capture_output=True, text=True, timeout=10)
                processes = result.stdout.lower()
                
                for pattern in edr_patterns:
                    if pattern in processes:
                        security_info['edr_detected'] = True
                        security_info['security_tools'].append(pattern)
                        
            except (subprocess.TimeoutExpired, FileNotFoundError):
                pass
            
            # 检测防火墙状态
            firewall_commands = [
                ['systemctl', 'is-active', 'firewalld'],
                ['systemctl', 'is-active', 'ufw'],
                ['iptables', '-L']
            ]
            
            for cmd in firewall_commands:
                try:
                    result = subprocess.run(cmd, capture_output=True, text=True, timeout=5)
                    if result.returncode == 0 and 'active' in result.stdout:
                        security_info['firewall_active'] = True
                        break
                except (subprocess.TimeoutExpired, FileNotFoundError):
                    continue
            
            # 检测文件完整性监控(FIM)
            fim_paths = [
                '/usr/bin/aide',
                '/usr/bin/tripwire',
                '/usr/bin/samhain'
            ]
            
            for path in fim_paths:
                if os.path.exists(path):
                    security_info['fim_detected'] = True
                    security_info['security_tools'].append(os.path.basename(path))
            
            return security_info
            
        except Exception as e:
            print("[-] 安全工具检测失败: {}".format(e))
            return {}
    
    def detect_service_status(self):
        """关键服务状态检测"""
        try:
            service_info = {}
            
            # SSH服务检测
            try:
                result = subprocess.run(['systemctl', 'is-active', 'sshd'], 
                                      capture_output=True, text=True, timeout=5)
                service_info['ssh_active'] = result.returncode == 0
                
                # SSH配置检测
                if os.path.exists('/etc/ssh/sshd_config'):
                    with open('/etc/ssh/sshd_config', 'r') as f:
                        ssh_config = f.read()
                    service_info['ssh_pubkey_auth'] = 'PubkeyAuthentication yes' in ssh_config
                else:
                    service_info['ssh_pubkey_auth'] = False
                    
            except (subprocess.TimeoutExpired, FileNotFoundError):
                service_info['ssh_active'] = False
                service_info['ssh_pubkey_auth'] = False
            
            # Cron服务检测
            try:
                result = subprocess.run(['systemctl', 'is-active', 'cron'], 
                                      capture_output=True, text=True, timeout=5)
                if result.returncode != 0:
                    result = subprocess.run(['systemctl', 'is-active', 'crond'], 
                                          capture_output=True, text=True, timeout=5)
                service_info['cron_active'] = result.returncode == 0
            except (subprocess.TimeoutExpired, FileNotFoundError):
                service_info['cron_active'] = False
            
            # Systemd检测
            service_info['systemd_available'] = os.path.exists('/bin/systemctl') or os.path.exists('/usr/bin/systemctl')
            
            return service_info
            
        except Exception as e:
            print("[-] 服务状态检测失败: {}".format(e))
            return {}
    
    def detect_sensitive_paths(self):
        """敏感路径检测"""
        try:
            path_info = {}
            
            # SSH目录权限
            ssh_dir = os.path.expanduser('~/.ssh')
            if os.path.exists(ssh_dir):
                stat_info = os.stat(ssh_dir)
                path_info['ssh_dir_writable'] = os.access(ssh_dir, os.W_OK)
                path_info['ssh_dir_mode'] = oct(stat_info.st_mode)[-3:]
            else:
                path_info['ssh_dir_writable'] = True  # 可以创建
                path_info['ssh_dir_mode'] = None
            
            # sudoers文件权限
            sudoers_file = '/etc/sudoers'
            if os.path.exists(sudoers_file):
                path_info['sudoers_writable'] = os.access(sudoers_file, os.W_OK)
            else:
                path_info['sudoers_writable'] = False
            
            # 系统目录权限
            system_dirs = ['/etc/profile.d', '/etc/systemd/system', '/var/spool/cron']
            path_info['writable_system_dirs'] = []
            
            for dir_path in system_dirs:
                if os.path.exists(dir_path) and os.access(dir_path, os.W_OK):
                    path_info['writable_system_dirs'].append(dir_path)
            
            return path_info
            
        except Exception as e:
            print("[-] 敏感路径检测失败: {}".format(e))
            return {}
    
    def generate_environment_profile(self):
        """生成目标环境画像"""
        try:
            if not self.verify_root_privilege():
                return False
            
            print("[*] 正在生成目标环境画像...")
            
            # 收集各类信息
            system_info = self.detect_system_info()
            security_info = self.detect_security_tools()
            service_info = self.detect_service_status()
            path_info = self.detect_sensitive_paths()
            
            # 生成环境画像
            self.environment_profile = {
                'timestamp': self.detection_timestamp,
                'detection_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'system': system_info,
                'security': security_info,
                'services': service_info,
                'paths': path_info
            }
            
            # 生成防御等级评估
            defense_level = self.assess_defense_level()
            self.environment_profile['defense_level'] = defense_level
            
            # 输出画像摘要
            self.print_profile_summary()
            
            return True
            
        except Exception as e:
            print("[-] 环境画像生成失败: {}".format(e))
            return False
    
    def assess_defense_level(self):
        """评估防御等级"""
        try:
            score = 0
            level_info = {
                'score': 0,
                'level': 'low',
                'description': '',
                'factors': []
            }
            
            security = self.environment_profile.get('security', {})
            
            # EDR检测 (+30分)
            if security.get('edr_detected', False):
                score += 30
                level_info['factors'].append('检测到EDR/安全软件')
            
            # 防火墙激活 (+15分)
            if security.get('firewall_active', False):
                score += 15
                level_info['factors'].append('防火墙处于激活状态')
            
            # FIM检测 (+25分)
            if security.get('fim_detected', False):
                score += 25
                level_info['factors'].append('检测到文件完整性监控')
            
            # 多个安全工具 (+10分)
            if len(security.get('security_tools', [])) > 1:
                score += 10
                level_info['factors'].append('检测到多个安全工具')
            
            # 确定防御等级
            if score >= 50:
                level_info['level'] = 'high'
                level_info['description'] = '高防御环境 - 有EDR+FIM等高级防护'
            elif score >= 20:
                level_info['level'] = 'medium'
                level_info['description'] = '中防御环境 - 有基础防护工具'
            else:
                level_info['level'] = 'low'
                level_info['description'] = '低防御环境 - 基础或无防护'
            
            level_info['score'] = score
            return level_info
            
        except Exception as e:
            print("[-] 防御等级评估失败: {}".format(e))
            return {'level': 'unknown', 'score': 0, 'description': '评估失败'}
    
    def print_profile_summary(self):
        """打印环境画像摘要"""
        try:
            print("\n" + "="*60)
            print("[+] 目标环境画像生成完成")
            print("="*60)
            
            # 系统信息
            system = self.environment_profile.get('system', {})
            print("[*] 系统信息: {0} {1}".format(system.get('os_name', 'Unknown'), system.get('os_version', '')))
            print("[*] 内核版本: {0}".format(system.get('kernel', 'Unknown')))
            print("[*] 系统架构: {0}".format(system.get('architecture', 'Unknown')))
            
            # 安全状态
            security = self.environment_profile.get('security', {})
            print("[*] EDR检测: {0}".format('是' if security.get('edr_detected') else '否'))
            print("[*] 防火墙状态: {0}".format('激活' if security.get('firewall_active') else '未激活'))
            print("[*] FIM检测: {0}".format('是' if security.get('fim_detected') else '否'))
            
            if security.get('security_tools'):
                print("[*] 检测到安全工具: {0}".format(', '.join(security['security_tools'])))
            
            # 服务状态
            services = self.environment_profile.get('services', {})
            print("[*] SSH服务: {}".format('运行中' if services.get('ssh_active') else '未运行'))
            print("[*] SSH密钥认证: {}".format('支持' if services.get('ssh_pubkey_auth') else '不支持'))
            print("[*] Cron服务: {}".format('运行中' if services.get('cron_active') else '未运行'))
            print("[*] Systemd: {}".format('可用' if services.get('systemd_available') else '不可用'))
            
            # 防御等级
            defense = self.environment_profile.get('defense_level', {})
            print("\n[+] 防御等级评估: {}".format(defense.get('level', 'unknown').upper()))
            print("[+] 防御描述: {}".format(defense.get('description', '未知')))
            print("[+] 防御评分: {}/100".format(defense.get('score', 0)))
            
            if defense.get('factors'):
                print("[+] 防御因素:")
                for factor in defense['factors']:
                    print("    - {}".format(factor))
            
            print("="*60)
            
        except Exception as e:
            print("[-] 画像摘要输出失败: {}".format(e))
    
    def save_profile(self, filepath=None):
        """保存环境画像到文件"""
        try:
            if not filepath:
                filepath = "/tmp/.env_profile_{}.json".format(self.detection_timestamp)
            
            with open(filepath, 'w') as f:
                json.dump(self.environment_profile, f, indent=2, ensure_ascii=False)
            
            print("[+] 环境画像已保存到: {}".format(filepath))
            return filepath
            
        except Exception as e:
            print("[-] 环境画像保存失败: {}".format(e))
            return None
    
    def load_profile(self, filepath):
        """从文件加载环境画像"""
        try:
            with open(filepath, 'r') as f:
                self.environment_profile = json.load(f)
            
            print("[+] 环境画像已从 {} 加载".format(filepath))
            return True
            
        except Exception as e:
            print("[-] 环境画像加载失败: {}".format(e))
            return False
    
    def get_defense_level(self):
        """获取防御等级"""
        return self.environment_profile.get('defense_level', {}).get('level', 'unknown')
    
    def get_profile(self):
        """获取完整环境画像"""
        return self.environment_profile


def main():
    """主函数 - 测试用"""
    print("Root权限管理器 - 环境探测测试")
    
    manager = RootPrivilegeManager()
    
    if manager.generate_environment_profile():
        # 保存画像
        profile_file = manager.save_profile()
        
        # 显示防御等级
        defense_level = manager.get_defense_level()
        print("\n[+] 检测完成，防御等级: {}".format(defense_level))
        
    else:
        print("[-] 环境探测失败")


if __name__ == "__main__":
    main()